﻿#define NORMAL_TEST
//#define ALERT_TEST
//#define BROADCAST_TEST

using LibNiconico.NiconicoApi;
using LibNiconico.NiconicoApi.Alert;
using LibNiconico.NiconicoApi.Exceptions;
using LibNiconico.NiconicoApi.Lives.Broadcast;
using LibNiconico.NiconicoApi.Mylist;
using LibNiconico.NiconicoApi.Utils;
using NiconicoApiHelper_ApiAccessTest.Properties;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;




namespace NiconicoApiHelper_ApiAccessTest
{
    class ApiTest
    {
        private static string mail;
        private static string password;

        private const string testVideoId = "sm20049558";

        private const string testLiveId = "lv19800507";

        private const string testUserId = "29449369";

        private static NicoApiHelper helper = new NicoApiHelper();

        private static NicoAlertApiHelper alertHelper = new NicoAlertApiHelper();

        static void Main(string[] args)
        {

            //非ログインテスト
            //failVideoTest();
            Console.Write(@"setting:
edit setting:e
load setting:l
default setting:d
select:");
            var readText =  Console.ReadLine();

            switch (readText.ToLower())
            {
                case "e":
                    Console.Write("Mail:");
                    Settings.Default.Mail = Console.ReadLine();
                    Console.Write("Password:");
                    Settings.Default.Password = Console.ReadLine();
                    mail = Settings.Default.Mail;
                    password = Settings.Default.Password;
                    Settings.Default.Save();

                    break;

                case "l":
                    mail = Settings.Default.Mail;
                    password = Settings.Default.Password;

                    break;

                case "d":
                    mail = "nicotestuser@mail.goo.ne.jp";
                    password = "niconico";
                    
                    break;
            }

            

            login();
            
#if NORMAL_TEST
            Task.Delay(TimeSpan.FromSeconds(3));

            //動画情報取得テスト
            videoTest();
            Task.Delay(TimeSpan.FromSeconds(3));
            //生放送テスト
            liveTest();
            Task.Delay(TimeSpan.FromSeconds(3));
            //マイリストテスト
            mylistAddTest();
            Task.Delay(TimeSpan.FromSeconds(3));
            //ユーザThumbテスト
            userThumbTest();

            Task.Delay(TimeSpan.FromSeconds(3));



            Task.Delay(TimeSpan.FromSeconds(3));
#endif
            
            
#if ALERT_TEST
            //アラートログインテスト
            alertLoginTest();
            Task.Delay(TimeSpan.FromSeconds(3));
            alertLoginFailTest();

            Task.Delay(TimeSpan.FromSeconds(3));

            alertGetInfoTest();

            Task.Delay(TimeSpan.FromSeconds(3));

            getAlertStatusTest();

            Task.Delay(TimeSpan.FromSeconds(3));
#endif

#if BROADCAST_TEST
            crateLiveBroadcastTest();
#endif
            
            Console.WriteLine("---------------------------testEnd------------------------");
            Console.ReadLine();
            
            
        }




        private static void failVideoTest()
        {
            try
            {
                var thumbInfoResponse = helper.VideoApi.GetThumbInfoAsync(testVideoId).GetAwaiter().GetResult();
                dispTest("thumbInfo取得非ログインテスト", false, "失敗");
                return;
            }
            catch (NicoApiException e)
            {
                dispTest("thumbInfo取得非ログインテスト", true, "成功");
                return;
            }
            catch (Exception e)
            {
                dispTest("thumbInfo取得非ログインテスト", false, "失敗");
            }

        }


        private static void videoTest()
        {
            var thumbInfoResponse = helper.VideoApi.GetThumbInfoAsync(testVideoId).GetAwaiter().GetResult();
            dispTest("thumbInfo取得テスト,ステータス", thumbInfoResponse.Status.Code == NicoApiResponseStatusCode.OK, "status=" + thumbInfoResponse.Status.Code);
            dispTest("thumbInfo取得テスト,エラーコード", thumbInfoResponse.Error.Code == NicoErrorCode.None, "code=" + thumbInfoResponse.Error.Code);
            dispTest("thumbInfo取得テスト,id", thumbInfoResponse.Thumb.VideoId == testVideoId, "videoId=" + thumbInfoResponse.Thumb.VideoId);

        }

        private static void liveTest()
        {
            var connectionResponse = helper.LiveApi.ConnectLiveAsync(testLiveId).GetAwaiter().GetResult();
            var playerStatusResponse = connectionResponse.PlayerStatusResponse;
            dispTest("playerStatus取得テスト,ステータス", playerStatusResponse.Succeed, "succeed=" + playerStatusResponse.Succeed);
            dispTest("playerStatus取得テスト,Status", playerStatusResponse.Status.Code == NicoApiResponseStatusCode.OK, "status=" + playerStatusResponse.Status.Code);
            dispTest("playerStatus取得テスト,エラーコード", playerStatusResponse.Error.Code == NicoErrorCode.None, "errorCode=" + playerStatusResponse.Error.Code);
            dispTest("playerStatus取得テスト,id", playerStatusResponse.PlayerStatus.Stream.Id == testLiveId, "liveId=" + playerStatusResponse.PlayerStatus.Stream.Id);
            dispTest("playerStatus取得テスト,タイトル", playerStatusResponse.PlayerStatus.Stream.Title == "麻生太郎元首相 ニコニコ動画独占インタビュー公開！", "title=" + playerStatusResponse.PlayerStatus.Stream.Title);

        }

        private static void mylistAddTest()
        {
            var mylistAddRequestResponse = helper.MylistApi.AddMylistRequestAsync(testVideoId).GetAwaiter().GetResult();

            var mylistAddExecuteResponse = helper.MylistApi.AddMylistExecuteAsync(mylistAddRequestResponse.MylistItems.First(), mylistAddRequestResponse).GetAwaiter().GetResult();

            dispTest("マイリスト追加テスト,Succeed", mylistAddExecuteResponse.Result.Succeed, "succeed=" + mylistAddExecuteResponse.Result.Succeed);
            dispTest("マイリスト追加テスト,ステータス", mylistAddExecuteResponse.Result.ResultCode == NicoMylistAddResultCode.Succeed, "resultCode=" + mylistAddExecuteResponse.Result.ResultCode);

        }


        


        private static void userThumbTest()
        {
            var userThumbResponse = helper.UserApi.GetThumbUserAsync(testUserId).GetAwaiter().GetResult();

            dispTest("ユーザThumbテスト,UserName", userThumbResponse.UserName == "NicoTestUser", "userName=" + userThumbResponse.UserName);
            dispTest("ユーザthumbテスト,IconPath", userThumbResponse.UserImagePath != "", "imagePath = " + userThumbResponse.UserImagePath);
        }

        private static void alertLoginTest()
        {
            var response = alertHelper.LoginAsync(mail, password).GetAwaiter().GetResult();
            dispTest("アラートログインテスト", response.Succeed, "succeed=" + response.Succeed);
        }

        private static void alertLoginFailTest()
        {
            var failLoginAlertHeler = new NicoAlertApiHelper();
            var response = failLoginAlertHeler.LoginAsync("failMail","failPassword").GetAwaiter().GetResult();
            dispTest("アラートログイン失敗テスト",response.Succeed != true,"succeed=" + response.Succeed);
            dispTest("アラートログインエラーコード", response.Error.Code == NicoAlertErrorCode.InvalidMailOrPassword, "code=" + NicoAlertErrorCode.InvalidMailOrPassword);

        }

        private static void alertGetInfoTest()
        {
            var resposne = alertHelper.GetAlertInfoAsync().GetAwaiter().GetResult();
            dispTest("アラート情報結果テスト", resposne.Succeed, "succeed=" + resposne.Succeed);
            dispTest("アラート情報エラーコードテスト", resposne.Error.Code == NicoAlertErrorCode.None, "errorCode=" + resposne.Error.Code);
            dispTest("アラート情報アドレステスト", resposne.AlertStatus.MessageServer.Addr != "", "addr=" + resposne.AlertStatus.MessageServer.Addr);
            dispTest("アラート情報ポート番号テスト", resposne.AlertStatus.MessageServer.Port != -1, "port=" + resposne.AlertStatus.MessageServer.Port);

            var alertClient = resposne.AlertClient;

            alertClient.Received += (m) =>
            {
                foreach (var message in m.Messages)
                {
                    Console.WriteLine("id=" + message.Id + ",chanelOrCommunity=" + message.CommunityOrChannnelId + ",ownerId=" + message.OwnerId);

                    var streamInfoResponse = alertHelper.GetStreamInfoAsync(message.Id).GetAwaiter().GetResult();

                    Console.WriteLine("title=" + streamInfoResponse.AlertStreamInfo.Title + ",community=" + streamInfoResponse.AlertStreamInfo.DefaultCommunity);

                }
            };
            alertClient.ConnectAsync().GetAwaiter().GetResult();


            Console.ReadLine();

            alertClient.Dispose();
        }

        private static void getAlertStatusTest()
        {
            var response = alertHelper.GetAlertStatusAsync().GetAwaiter().GetResult();
            dispTest("アラートステータステスト", response.Succeed, "succeed=" + response.Succeed);
            var alertClient = response.AlertClient;

            alertClient.Received += (m) =>
            {
                foreach (var message in m.Messages)
                {
                    Console.WriteLine("id=" + message.Id + ",chanelOrCommunity=" + message.CommunityOrChannnelId + ",ownerId=" + message.OwnerId);
                }
            };
            alertClient.ConnectAsync().GetAwaiter().GetResult();


            Console.ReadLine();

            alertClient.Dispose();
            
        }

        private static void dispTest(string testName, bool result,string message)
        {
            Console.WriteLine(testName + ":" + (result ? "OK":"NG") + "," + message);

        }


        private static void crateLiveBroadcastTest()
        {

            var broadcastingPossibleCommunityInfo = helper.BroadcastApi.GetBroadcastableInfoAsync().GetAwaiter().GetResult();


            //放送可能なコミュ情報を取得
            if (broadcastingPossibleCommunityInfo.Succeed)
            {

                dispTest("放送可能コミュ情報取得", true, "コミュ情報取得成功");

                var broadcastingPossibleCommunity = from community in broadcastingPossibleCommunityInfo.BroadcastableCommunityInfos
                                                    where community.CommunityId == "co1203895"
                                                    select community;


                //放送枠作成
                if (broadcastingPossibleCommunity.Count() > 0)
                {
                    var queryInfo = new NicoLiveBroadcastCreateQueryInfo();

                    queryInfo.Title = "test";
                    queryInfo.DefaultCommunity = broadcastingPossibleCommunity.First();
                    queryInfo.Description = "description";
                    queryInfo.Tags.Add("testTag", true);
                    queryInfo.TwitterTag = "testTwitterTag";
                    queryInfo.TimeShiftEnabled = true;
                    queryInfo.TwitterDisabled = false;
                    queryInfo.PublicStatus = NicoLivePublicStatus.CommunityOnly;
                    queryInfo.PrimaryCategory = PrimaryCategory.General;

                    var createResponse = helper.BroadcastApi.CreateLiveBroadcastAsync(queryInfo).GetAwaiter().GetResult();

                    dispTest("指定したコミュ情報取得判定", true, "communityId=" + queryInfo.DefaultCommunity.CommunityId);

                    //放送開始
                    if (createResponse.Succeed)
                    {

                        var startResponse = helper.BroadcastApi.StartBroadcastAsync(createResponse.LiveInfo).GetAwaiter().GetResult();


                        if (startResponse.Succeed)
                        {
                            dispTest("放送開始判定", true, "放送開始成功");


                            var stopResponse = helper.BroadcastApi.StopBroadcastAsync(createResponse.LiveInfo.LiveId).GetAwaiter().GetResult();


                            dispTest("放送停止判定", stopResponse.Succeed, "Succeed = " + stopResponse.Succeed);
                        }
                        else
                        {
                            dispTest("放送開始判定", false, "放送開始失敗");
                        }

                    }
                    else
                    {
                        dispTest("放送枠作成判定", false, "放送枠作成失敗,message=" + createResponse.Message);
                    }

                }
                else
                {

                    dispTest("指定したコミュ情報取得判定", false, "コミュ情報取得失敗");
                }
                
            }
            else
            {
                dispTest("放送可能コミュ情報取得", false, "コミュ情報取得失敗");
            }

            
            

        }
        


        private static void login()
        {
            helper.LoginAsync(mail, password).GetAwaiter().GetResult();
        }
    }
}
